/***************************************************************************
 创建者: 华磊
 开始时间: 2018.8.14
 copyright: (C) 华友高科
 修改说明: (每次有修改就添加一条，带有 修改人，修改时间，修改描述)
 example (1) hualei 2017.5.8 类的具体实现代码编写

 ***************************************************************************/
#include "canbusrfid.h"
#include <QDebug>
#include <QString>

#define D_RECEIVE_WAIT_COUNT_MAX 2000
#define D_RECEIVE_WAIT_SLEEP_TIME 500

CanbusRfid::CanbusRfid(QString configFileNameIn, int aliasIn, int busNumberIn, int deviceIdIn,
                       CanbusDeviceDriver *canbusDriverIn)
{
//    tcpVrep=NULL;
    isInitialedOk=false;
    alias=aliasIn;
    busNumber=busNumberIn;
    canbusDriver=canbusDriverIn;
    deviceId=deviceIdIn;
    writeCardCommandFlag=false;
    for(int i=0;i<8;i++)
    {
        cardValue[i]=0;
    }

    isCardDetected=false;

    initial(configFileNameIn);

}

CanbusRfid::~CanbusRfid()
{
//    if(  tcpVrep!=NULL )
//    {
//        tcpVrep->close();
    //    }
}

int CanbusRfid::startPdoMode()
{
    if( false==isInitialedOk)
    {
        return -1;
    }


    int tmpReturn;
    switch(vendorId)
    {
        case E_VENDOR_ID_AI_KONG:
        {
           return 1;

            break;
        }
    case E_VENDOR_ID_FoSanXingSong:
    {
       return 1;

        break;
    }

    default:
    {
        E_NODE_MANAGE commandIn=E_NODE_MANAGE_START_PDO;
         tmpReturn=canbusDriver->manageNode(deviceId,busNumber,alias,commandIn);
         if(1==tmpReturn)
         {
             return 1;
         }
         else
         {
             return tmpReturn;
         }
         break;
    }
    }

    return -1;
}

int CanbusRfid::getAlias()
{
    return alias;
}

int CanbusRfid::sendDataRequestCommand()
{
    QVector<unsigned char> tmpData;
    tmpData.resize(1);
    int keyReturn = canbusDriver->sendData(deviceId, busNumber, alias, tmpData);
    if(1!=keyReturn)
    {
        qDebug()<<"error, getCurrentTagData error!";
        return -1;

    }
    return 1;
}

int CanbusRfid::processDataFrame(unsigned char cardValueOut[], bool &isCardDetectedOut)
{
    switch(vendorId)
    {
    case E_VENDOR_ID_FoSanXingSong:
    {
        return processDataFrame_XingSong(cardValueOut,isCardDetectedOut);
        break;
    }
    case E_VENDOR_ID_SHANGHAI_YUANBEN:
    {
        return processDataFrame_YuanBen(cardValueOut,isCardDetectedOut);
        break;
    }
    default:
    {
        qDebug()<<"CanbusMaganetic unsupport vendorid"<<vendorId;
        return -1;
    }
    }
    return -1;
}

int CanbusRfid::getCurrentTagData(unsigned char cardValueOut[], bool &isCardDetectedOut)
{
    QVector<unsigned char> tmpData;
    tmpData.resize(1);
    int keyReturn = canbusDriver->sendData(deviceId, busNumber, alias, tmpData);
    if(1!=keyReturn)
    {
        qDebug()<<"error, getCurrentTagData error!";
        return -1;

    }
    //receive sdo data
    QVector<unsigned int> frameIdOut;
    QVector<QVector<unsigned char> > dataListOut;
    int tryCount=0;
    while(tryCount<D_RECEIVE_WAIT_COUNT_MAX)
    {
        keyReturn = canbusDriver->getReceiveNum(deviceId, busNumber);
        if(keyReturn>1)
        {
            keyReturn = canbusDriver->receiveData(deviceId, busNumber,
                                                  frameIdOut, dataListOut);
            if(keyReturn>0)
            {
                break;
            }
            else
            {
                return -2;
            }
        }
        tryCount++;
        usleep(D_RECEIVE_WAIT_SLEEP_TIME);

    }
    if(keyReturn<=0)
    {
        qDebug()<<"error, canbus receive error!";
//        addMsg(ENUM_MSG_ERROR, "EcatMaster", "CanbusCom" , 1915, -1 );
        return -3;
    }

    //process data
    int rfidFrameCount=0;
    for(int i=0;i<frameIdOut.size();i++)
    {
        if(frameIdOut[i]==alias)
        {
            if(0==rfidFrameCount)
            {
                //            dataListOut[i][2];//read state;
                //            dataListOut[i][3];//sensor strength;
//                            qDebug()<<dataListOut[i][2] <<"------"<<dataListOut[i][3];

                            cardValueOut[0]=dataListOut[i][4];
                            cardValueOut[1]=dataListOut[i][5];
                            cardValueOut[2]=dataListOut[i][6];
                            cardValueOut[3]=dataListOut[i][7];
                            rfidFrameCount++;
            }
            else if(1==rfidFrameCount)
            {
//                            qDebug()<<dataListOut[i][2] <<"------"<<dataListOut[i][3];
                            cardValueOut[4]=dataListOut[i][4];
                            cardValueOut[5]=dataListOut[i][5];
                            cardValueOut[6]=dataListOut[i][6];
                            cardValueOut[7]=dataListOut[i][7];
                            isCardDetectedOut=dataListOut[i][2];
                            return 1;
            }



        }
        else
        {
//            qDebug()<<"warning, can receive unknow frameId frame="<<frameIdOut[i];
            continue;
        }
    }
    return -4;
}

int CanbusRfid::getCurrentTagDataFromBuffer(QVector<unsigned char> &cardValueOut, bool &isCardDetectedOut)
{
    cardValueOut.clear();
    for(int i=0;i<8;i++)
    {
        cardValueOut.append(cardValue[i]);
    }
    isCardDetectedOut=isCardDetected;
    return 1;
}

int CanbusRfid::writeTagDataUndirect(QVector<unsigned char> cardValueIn)
{

    for(int i=0;i<8;i++)
    {
        if(i<cardValueIn.size())
        {
            cardValue_command[i]=cardValueIn[i];
        }
        else
        {
            cardValue_command[i]=0;
        }

    }
    writeCardCommandFlag=true;
    return 1;

}

bool CanbusRfid::isInitialOkStatus()
{
    return isInitialedOk;
}

int CanbusRfid::writeRfidCardData(QVector<unsigned char> cardValueIn)
{
    switch(vendorId)
    {
    case E_VENDOR_ID_FoSanXingSong:
    {
        return writeRfidCardData_XingSong(cardValueIn);
        break;
    }
    case E_VENDOR_ID_SHANGHAI_YUANBEN:
    {
        return writeRfidCardData_YuanBen(cardValueIn);
        break;
    }
    default:
    {
        qDebug()<<"CanbusMaganetic unsupport vendorid"<<vendorId;
        return -1;
    }
    }
    return -1;
}

int CanbusRfid::writeRfidCardData_XingSong(QVector<unsigned char> cardValueIn)
{
    if(8!=cardValueIn.size())
    {
        return -1;
    }
    //只支持４字节的值
    cardValueIn[4]=0;
    cardValueIn[5]=0;
    cardValueIn[6]=0;
    cardValueIn[7]=0;

    int keyReturn = canbusDriver->sendData(deviceId, busNumber, alias, cardValueIn);
    if(1!=keyReturn)
    {
        qDebug()<<"error, getCurrentTagData error!";
        return -1;

    }
    //receive sdo data
    QVector<unsigned int> frameIdOut;
    QVector<QVector<unsigned char> > dataListOut;
    int tryCount=0;
    while(tryCount<10)
    {
        keyReturn = canbusDriver->receiveData(deviceId, busNumber, frameIdOut, dataListOut);
        if(keyReturn>0)
        {
            break;
        }
        tryCount++;
        usleep(1000);

    }
    if(keyReturn<=0)
    {
        qDebug()<<"error, canbus receive error!";
//        addMsg(ENUM_MSG_ERROR, "EcatMaster", "CanbusCom" , 1915, -1 );
        return -1;
    }

    //process data
    for(int i=0;i<frameIdOut.size();i++)
    {
        if(frameIdOut[i]==alias)
        {
//            dataListOut[i][1];// write state;
//            dataListOut[i][2];// read state;
             //            dataListOut[i][3];//sensor strength;

           if(0!=dataListOut[i][1])
           {
               return -1;
           }
           return 1;

        }
        else
        {
//            qDebug()<<"warning, can receive unknow frameId frame!";
            continue;
        }
    }
    return -1;
}

int CanbusRfid::writeRfidCardData_YuanBen(QVector<unsigned char> cardValueIn)
{
    return -1;
}

int CanbusRfid::updateData()
{
//    int tmpKey=getCurrentTagData(cardValue,isCardDetected);
    int tmpKey=processDataFrame(cardValue,isCardDetected);
    if(1==tmpKey)
    {

    }
    else
    {
        return tmpKey;
    }

    if(true==writeCardCommandFlag)
    {
        QVector<unsigned char> tmpCardValue;
        tmpCardValue.resize(8);
        for(int i=0;i<8;i++)
        {
            tmpCardValue[i]=cardValue_command[i];
        }
        if(1==writeRfidCardData(tmpCardValue))
        {
           writeCardCommandFlag=false;
        }
        else
        {
            writeCardCommandFlag=false;
            return -1;
        }

    }

    return 1;
}

int CanbusRfid::getDeviceAddressInfo(int &aliasOut, int &busNumberOut, int &deviceIdOut)
{
    aliasOut=alias;
    busNumberOut=busNumber;
    deviceIdOut=deviceId;
    return 1;
}

int CanbusRfid::getVendorId()
{
    return vendorId;
}

#define D_SDO_TRY_MAX 5
int CanbusRfid::downloadSdoConfig()
{

    if( false==isInitialedOk)
    {
        return -1;
    }

    for(int i=0;i<sdoConfigList.size();i++)
    {
        for(int k=0;k<=D_SDO_TRY_MAX;k++)
        {
            int tmpReturn=canbusDriver->sdoDownload(deviceId,busNumber,alias,sdoConfigList[i].index
                                     ,sdoConfigList[i].subindex,sdoConfigList[i].value,sdoConfigList[i].byteLength);
            if(1==tmpReturn)
            {
                break;
            }
            else if(D_SDO_TRY_MAX==k)
            {
                qDebug()<<"downloadServoSdoConfig error,D_SDO_TRY_MAX"<<D_SDO_TRY_MAX
                       <<" alias"<<alias<<" index"<<sdoConfigList[i].index
                      <<" subindex"<<sdoConfigList[i].subindex
                     <<" byteLength"<<sdoConfigList[i].byteLength
                    <<" value"<<sdoConfigList[i].value;
                return -1;
            }
        }
    }



    return 1;
}

int CanbusRfid::processDataFrame_XingSong(unsigned char cardValueOut[], bool &isCardDetectedOut)
{
    QQueue<FrameData> userFrameBuffersOut;
    canbusDriver->getUserBuffer(userFrameBuffersOut);

    //process data
    int rfidFrameCount=0;
    int tmpReturn=-1;
    for(int i=0;i<userFrameBuffersOut.size();i++)
    {
        if(userFrameBuffersOut[i].frameId==alias)
        {
            isCardDetectedOut=userFrameBuffersOut[i].data[2];
            //不支持卡数据为８字节，因为无法判断哪帧为高数据字节。
            if(0==userFrameBuffersOut[i].data[4] && 0==userFrameBuffersOut[i].data[5]
                   && 0==userFrameBuffersOut[i].data[6] && 0==userFrameBuffersOut[i].data[7] )
            {
                tmpReturn=1;
            }
            else
            {
                cardValueOut[0]=userFrameBuffersOut[i].data[4];
                cardValueOut[1]=userFrameBuffersOut[i].data[5];
                cardValueOut[2]=userFrameBuffersOut[i].data[6];
                cardValueOut[3]=userFrameBuffersOut[i].data[7];
                cardValueOut[4]=0;
                cardValueOut[5]=0;
                cardValueOut[6]=0;
                cardValueOut[7]=0;

                return 1;
            }

            //接收逻辑有问题。
//            if(0==rfidFrameCount)
//            {
//                //            dataListOut[i][2];//read state;
//                //            dataListOut[i][3];//sensor strength;
////                            qDebug()<<dataListOut[i][2] <<"------"<<dataListOut[i][3];

//                            cardValueOut[0]=userFrameBuffersOut[i].data[4];
//                            cardValueOut[1]=userFrameBuffersOut[i].data[5];
//                            cardValueOut[2]=userFrameBuffersOut[i].data[6];
//                            cardValueOut[3]=userFrameBuffersOut[i].data[7];
//                            rfidFrameCount++;
//            }
//            else if(1==rfidFrameCount)
//            {
////                            qDebug()<<dataListOut[i][2] <<"------"<<dataListOut[i][3];
//                            cardValueOut[4]=userFrameBuffersOut[i].data[4];
//                            cardValueOut[5]=userFrameBuffersOut[i].data[5];
//                            cardValueOut[6]=userFrameBuffersOut[i].data[6];
//                            cardValueOut[7]=userFrameBuffersOut[i].data[7];
//                            isCardDetectedOut=userFrameBuffersOut[i].data[2];
//                            return 1;
//            }



        }
        else
        {
//            qDebug()<<"warning, can receive unknow frameId frame="<<userFrameBuffersOut[i].frameId;
            continue;
        }
    }
    return tmpReturn;
}

int CanbusRfid::processDataFrame_YuanBen(unsigned char cardValueOut[], bool &isCardDetectedOut)
{
    //todo
    return -1;
}


int CanbusRfid::initial(QString fileName)
{
    qDebug()<<"CanbusRfid initial ,file name="<<fileName;
    driverConfig=new CanbusRfidConfig(fileName);
    if(true==driverConfig->isInitialOkStatus())
    {
        int tmpId;
        driverConfig->getVendorId(tmpId);
        vendorId=(E_VENDOR_ID) tmpId;
        driverConfig->getSdoConfig(sdoConfigList);
        isInitialedOk=true;
        return 1;
    }
    return -1;
}



